//---------------------------------------------------------------------------

#include <vcl.h>
#include <stdio.h>


#include "cbuffer.h"
#include "filters.h"
#include "RIFF.h"
#include "convert.h"

#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)


{


}
//---------------------------------------------------------------------------

void __fastcall TForm1::GetFileInfoClick(TObject *Sender)
{
FILE *MyFile;

if ( OpenDialog1->Execute())
   {
   // clear checkboxes
   EditFileType->Clear();
   EditAudioFormat->Clear();
   EditChannels->Clear();
   EditBitSample->Clear();
   EditSampleRate->Clear();

   MyFile = fopen ( OpenDialog1->FileName.c_str() , "rb" );
   if (MyFile!=NULL)
     {
     try
       {
       readRIFF MyRIFFfile(MyFile);
        EditFileType->Text=AnsiString(MyRIFFfile.getfiletype().c_str());
        EditAudioFormat->Text=AnsiString(MyRIFFfile.audioformatname().c_str());
        EditChannels->Text=AnsiString(MyRIFFfile.channels());
        EditBitSample->Text=AnsiString(MyRIFFfile.bitpersample());
        EditSampleRate->Text=AnsiString(MyRIFFfile.samplerate());
        MyRIFFfile.closeRIFFfile();
       }
     catch (int error)
       {
       switch (error)
         {
         case 10 : ShowMessage ("Unsupported File Format (Not a RIFF/RIFX)"); break;
         case 11 : ShowMessage ("Unsupported File Format (RIFF/RIFX format, not WAVE)"); break;

         case 20 : ShowMessage ("File Structure Error: \'fmt \' chunk too small"); break;
         case 21 : ShowMessage ("File Structure Error: \'fmt \' chunk missing");
         case 22 : ShowMessage ("File Structure Error: Incorrect File Size"); break;
         ShowMessage ("Unknown Error");
         }
       fclose(MyFile);
       }
     }
   }
}
//---------------------------------------------------------------------------



void __fastcall TForm1::TrackBarMainVolumeChange(TObject *Sender)
{
if ( !CheckBoxAllowOver100->Checked)
    TrackBarEchoVolume->Position = 100 - TrackBarMainVolume->Position;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::TrackBarEchoVolumeChange(TObject *Sender)
{
if ( !CheckBoxAllowOver100->Checked)
    TrackBarMainVolume->Position = 100 - TrackBarEchoVolume->Position;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::CheckBoxAllowOver100Click(TObject *Sender)
{
if ( CheckBoxAllowOver100->Checked )
    TrackBarEchoVolume->Position = 100 - TrackBarMainVolume->Position;
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ApplyClick(TObject *Sender)
{
FILE *MyFile;
FILE *OutFile;

if ( OpenDialog1->Execute())
   {
   // clear checkboxes
   EditFileType->Clear();
   EditAudioFormat->Clear();
   EditChannels->Clear();
   EditBitSample->Clear();
   EditSampleRate->Clear();

   MyFile = fopen ( OpenDialog1->FileName.c_str() , "rb" );
   if (MyFile!=NULL)
     {
     if ( SaveDialog1->Execute())
       {
       OutFile = fopen ( SaveDialog1->FileName.c_str() , "wb" );
       if (OutFile!=NULL)
         {
         try
           {
           readRIFF MyRIFFfile(MyFile);
           EditFileType->Text=AnsiString(MyRIFFfile.getfiletype().c_str());
           EditAudioFormat->Text=AnsiString(MyRIFFfile.audioformatname().c_str());
           EditChannels->Text=AnsiString(MyRIFFfile.channels());
           EditBitSample->Text=AnsiString(MyRIFFfile.bitpersample());
           EditSampleRate->Text=AnsiString(MyRIFFfile.samplerate());

           if ( MyRIFFfile.audioformat() == 1 )
             {
                cbuffer16 MyBuffer(MyRIFFfile.samplerate());
                signed short readtemp,writetemp;
                 filters MyFilters;

                // insert wav code
                 writeRIFF RIFFout(OutFile);
/*                 RIFFout.fmt_chunk( MyRIFFfile.audioformat(),
                                    MyRIFFfile.channels(),
                                    MyRIFFfile.samplerate(),
                                    MyRIFFfile.bitrate(),
                                    MyRIFFfile.bytepersample(),
                                    MyRIFFfile.bitpersample());
*/
        RIFFout.fmt_chunk(MyRIFFfile.readfmt());                                    
                 // Does it have to be like this?
                 // Using a struct as parameter for a function
                 // is not allowed, is there any better way of
                 // doing this?
                 MyRIFFfile.gotodatastart();
                 RIFFout.start_data_chunk();
                 // end wav
                   unsigned int currentsamplenr ;
                   unsigned short  currentchannel ;

                   for ( currentchannel = 0 ; currentchannel < MyRIFFfile.channels(); currentchannel++)
                     {

                     for ( currentsamplenr = 0; currentsamplenr < MyRIFFfile.samples(); currentsamplenr++)
                       {
                       readtemp = MyRIFFfile.readsample(currentsamplenr,currentchannel);
                       MyBuffer.write(readtemp);
                       for ( char b = 0; b < TrackBarEffectLevel->Position ; b++ )
                            MyBuffer.write(MyFilters.addecho(&MyBuffer,TrackBarMainVolume->Position,TrackBarEchoVolume->Position,MyRIFFfile.samplerate()*TrackBarDelayTime->Position/1000));
                       writetemp = MyFilters.addecho(&MyBuffer,TrackBarMainVolume->Position,TrackBarEchoVolume->Position,MyRIFFfile.samplerate()*TrackBarDelayTime->Position/1000);

                   // writecode
                        RIFFout.writesample(currentsamplenr,writetemp,currentchannel);
                       }
                   for ( unsigned int a = 0; a <  MyRIFFfile.samplerate() * TrackBarDelayTime->Position / 10000; a++)
                     {
                      MyBuffer.write(0);
                      for ( char b = 0; b < TrackBarEffectLevel->Position ; b++ )
                         MyBuffer.write(MyFilters.addecho(&MyBuffer,TrackBarMainVolume->Position,TrackBarEchoVolume->Position,MyRIFFfile.samplerate()*TrackBarDelayTime->Position/1000));
                      writetemp = MyFilters.addecho(&MyBuffer,TrackBarMainVolume->Position,TrackBarEchoVolume->Position,MyRIFFfile.samplerate()*TrackBarDelayTime->Position/1000);
                      currentsamplenr++;
                      RIFFout.writesample(currentsamplenr,writetemp,currentchannel);
//                    RIFFout.writesample(currentsamplenr,writetemp,1);
                      }                       // writecode
                    }
//                    fwrite (&writetemp, sizeof(writetemp), 1, OutFile);
                    fclose ( MyFile ) ;
                    //fclose ( OutFile ) ;
                    RIFFout.end_data_chunk();
                    RIFFout.close();
                    //}
                } else throw 31;
               }
           catch (int error)
             {
             switch (error)
               {
               case 10 : ShowMessage ("Unsupported File Format (Not a RIFF/RIFX)"); break;
               case 11 : ShowMessage ("Unsupported File Format (RIFF/RIFX format, not WAVE)"); break;

               case 20 : ShowMessage ("File Structure Error: \'fmt \' chunk too small"); break;
               case 21 : ShowMessage ("File Structure Error: \'fmt \' chunk missing");
               case 22 : ShowMessage ("File Structure Error: Incorrect File Size"); break;

               case 30 : ShowMessage ("Unsupported PCM format (Not 8 or 16 bit)");break;
               case 31 : ShowMessage ("Unsupported CODEC. Current program only supports PCM");break;

               case 40 : ShowMessage ("Out-of-Range Error: Channel not found");
               case 41 : ShowMessage ("Out-of-Range Error: Sample not found");
               ShowMessage ("Unknown Error");
               }
             }
           }
         }
       }
     }


}
//---------------------------------------------------------------------------



